#include <stdio.h>
#include <stdlib.h>

#define PDBR 0x6c
unsigned char memory_data[0x80][32], disk_data[0x80][32];
char s[1001];
int main()
{
    printf("Please input the physical memory file name: ");
    scanf("%s", s);
    FILE *fi = fopen(s, "r");
    for (int i = 0; i < 0x80; ++i)
    {
        while(fgetc(fi) != ':');
        for (int j = 0; j < 32; ++j)
            fscanf(fi, "%x", &memory_data[i][j]);
    }
    fclose(fi);
    
    printf("Please input the disk file name: ");
    scanf("%s", s);
    fi = fopen(s, "r");
    for (int i = 0; i < 0x80; ++i)
    {
        while(fgetc(fi) != ':');
        for (int j = 0; j < 32; ++j)
            fscanf(fi, "%x", &disk_data[i][j]);
    }
    fclose(fi);
    
    while(1)
    {
        int address;
        printf("Please input the virtual address:");
        scanf("%x", &address);
        int pde_index = address >> 10, 
            pde_content = memory_data[PDBR][pde_index];
        printf("pde index: 0x%x  pde content: (0x%x, valid %d, pfn 0x%x)\n", pde_index, pde_content, pde_content >> 7, pde_content & 127);
        if (pde_content >> 7)
        {
            int pte_index = (address >> 5) & 31, pte_content = memory_data[pde_content & 127][pte_index];
            printf("pte index: 0x%x  pte content: (0x%x, valid %d, pfn 0x%x)\n", pte_index, pte_content, pte_content >> 7, pte_content & 127);
            int address2 = ((pte_content & 127) << 5) | (address & 31);
            if (pte_content >> 7)
                printf("To Physical Address 0x%x --> Value: 0x%x\n", address2, memory_data[address2 >> 5][address2 & 31]);
            else
                if (pte_content != 0x7F)
                    printf("To Disk Sector Address 0x%x --> Value: 0x%x\n", address2, disk_data[address2 >> 5][address2 & 31]);
                else
                    printf("Fault.\n");
        }
        else
            printf("Fault.\n");
    }
    return 0;
}
